package com.testDemo.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import com.testDemo.enrty.Element;

/**
 * 拼装接口的html页面
 * @author Administrator
 */
public class MethodPageUtils {

    /**
     * 获取Excel的msg中每一行的信息
     * @param sheet
     * @return
     * @throws Exception
     */
    public static Element getRowContent(Sheet sheet, List<String> exceptions) throws Exception {

        Element msg = new Element();
        msg.setElementName("msg");
        msg.setCheckType("Y");
        msg.setExplan("报文体");
        msg.setFatherNode(true);
        msg.setFatherNodeName("body");
        int startRowNum = -1;
        int endRowNum = -1;
        long start = System.currentTimeMillis();
        boolean isStart = false;
        ok: for (Row row : sheet) {
            for (Cell cell : row) {
                String cellContent = "";
                if (TestUtils.isEmpty(cell)) {
                    continue;
                }
                cell.setCellType(Cell.CELL_TYPE_STRING); // 设置单元格格式为String
                cellContent = cell.getStringCellValue();
                // 判断是否为读取范围的开始,在遇到第一个"msg"的下一行开始
                if (!isStart && TestUtils.CHECK_KEY.equals(cellContent)) {
                    startRowNum = row.getRowNum() + 1;
                    isStart = true;
                }
                if ("para".equals(cellContent) || (!TestUtils.isEmpty(cellContent) && cellContent.contains("返回报文"))) {
                    endRowNum = row.getRowNum();// 备用字段的前一行,没有备用字段的规范就是其返回报文的前一行
                    break ok;
                }
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("用时:" + (end - start) + "\n开始行:" + startRowNum + "\n结束行:" + endRowNum);
        if (-1 != startRowNum) {
            Map ret = getChildElement(msg, sheet, startRowNum, endRowNum);
            msg = (Element) ret.get("element");
        }
        // 校验数据的正确性
        String elements = msg.getChildElements().toString();
        for (int i = startRowNum; i < endRowNum; i++) {
            Row row = sheet.getRow(i);
            Cell cell = row.getCell(1);
            String cellContent = "";
            if (TestUtils.isEmpty(cell)) {
                continue;
            }
            cell.setCellType(Cell.CELL_TYPE_STRING); // 设置单元格格式为String
            cellContent = cell.getStringCellValue();
            String checkResult = "--OK";
            if (!elements.contains(cellContent)) {
                checkResult = "未拼装";
                exceptions.add("第" + (i + 1) + "行节点:[" + cellContent + "]正确性校验:" + checkResult);
            }
        }
        // System.out.println(msg.getHtmlContent());
        return msg;
    }

    /**
     * 该方法为递归方法,获取父节点下的所有子节点
     * @param fatherElement
     * @param sheet
     * @param startRowNum
     * @param endRowNum
     *            整个sheet页的最后一行
     */
    private static Map getChildElement(Element fatherElement, Sheet sheet, int startRowNum, int endRowNum) {
        int rowNum = startRowNum;
        // Element lastFatherElement = new Element();
        Element lastElement = new Element();
        ok: for (rowNum = startRowNum; rowNum < endRowNum; rowNum++) {
            Row row = sheet.getRow(rowNum);
            List<String> rowContent = new ArrayList<String>();
            for (int j = 1; j <= 5; j++) {
                Cell cell = row.getCell(j);
                String cellContent = "";
                if (TestUtils.isEmpty(cell)) {
                    continue;
                }
                cell.setCellType(Cell.CELL_TYPE_STRING); // 设置单元格格式为String
                cellContent = cell.getStringCellValue();
                // 塞默认空值
                rowContent.add(TestUtils.isEmpty(cellContent) ? "" : cellContent);
            }
            // 该行有内容,则放入
            if (!TestUtils.isEmpty(rowContent)) {
                // 获取读取行的结束值,以读取到[para] 前有值的最后一行,同时,读取结束
                if (!TestUtils.isEmpty(rowContent.get(1)) && !fatherElement.getElementName().equals(rowContent.get(1))
                        && !rowContent.get(1).equals(lastElement.getElementName())) {
                    break ok;
                }
                // 元素的默认class等级为0,即没有层级 FIXME
                Element element = new Element(rowContent.get(0), rowContent.get(1), rowContent.get(2),
                        rowContent.get(3), rowContent.get(4), null, null);
                // 判断该节点是否是上一个元素的子节点
                if ("*,+".contains(element.getCheckType())) {
                    // 当前行为父元素行,调用方法为从下一行开始
                    element.setFatherNode(true);// 是父节点
                    // 设置该元素的层级class等级为父元素的下一级
                    element.setClassLevel(fatherElement.getClassLevel() + 1);
                    Map ret = getChildElement(element, sheet, row.getRowNum() + 1, endRowNum);
                    element = (Element) ret.get("element");
                    rowNum = (Integer) ret.get("rowNum") - 1;// 需要跟i++互相抵消,内层方法执行到的行数,下次循环应执行该行数
                }
                else if (element.getFatherNodeName().equals(lastElement.getElementName())) {
                    // 当前行为父元素下一行(子元素),调用方法为从当前行开始
                    lastElement.setFatherNode(true);// 是父节点
                    // 设置该元素的层级class等级为父元素的下一级
                    lastElement.setClassLevel(fatherElement.getClassLevel() + 1);
                    Map ret = getChildElement(lastElement, sheet, row.getRowNum(), endRowNum);
                    element = (Element) ret.get("element");
                    rowNum = (Integer) ret.get("rowNum") - 1;// 需要跟i++互相抵消,内层方法执行到的行数,下次循环应执行该行数
                    // 去掉上次循环已经放入fatherElement中的该父元素
                    fatherElement.getChildElements().remove(fatherElement.getChildElements().size() - 1);
                }
                else {
                    lastElement = element;
                }
                // createHtmlNode(element);// 根据节点生成html内容
                fatherElement.getChildElements().add(element);
            }
        }
        Map retMap = new HashMap();
        fatherElement.setHtmlContent(createHtmlNode(fatherElement));
        retMap.put("element", fatherElement);
        retMap.put("rowNum", rowNum);// 外层的方法从当前行开始执行
        return retMap;
    }

    /**
     * 拼装每一个父节点的html内容
     * @param rows
     */
    private static String createHtmlNode(Element element) {
        // 如果该节点已经拼装过了html,就不做拼装
        if (!TestUtils.isEmpty(element.getHtmlContent())) {
            return element.getHtmlContent();
        }
        String htmlContent = "";
        String checkType = element.getCheckType();
        // 元素的ID为元素名和其节点类型的拼装
        // String elementId = element.getElementName() + "," + checkType;
        String elementId = element.getElementName();
        if (element.isFatherNode()) {// 如果是父节点
            // 元素的class等级,不为0时拼装
            String classLevel = "";
            if (element.getClassLevel() != 0) {
                classLevel = element.getClassLevel() + "";
            }
            // 1,拼装父元素属性
            htmlContent = "<div id='" + elementId + "' class='dompart" + classLevel + " " + checkType
                    + "'  style='display: block'>";
            // 操作的div拼装
            htmlContent += "<div class='parentName'><img src='img/reduce.png' onclick='hidechild(this)' class='changepic'/>"
                    + "<lable>" + element.getElementName() + " " + element.getExplan() + "</lable>";
            // 如果是msg节点,拼装发送请求按钮
            if ("msg".equals(element.getElementName())) {
                htmlContent += "<button onclick='sendMsg(this)'>发送请求</button>";
            }
            // 若该节点可传多个,拼装add按钮
            if ("+*".contains(checkType)) {
                htmlContent += "<img alt='新增节点' src='img/adddom.png' class='addParentDom' onclick='addParentDom(this)'/>";
            }
            htmlContent += "</div>";// 操作div的结束
            // 拼装子元素节点
            if (!TestUtils.isEmpty(element.getChildElements())) {
                for (Element ele : element.getChildElements()) {
                    htmlContent += createHtmlNode(ele);
                }
            }
            htmlContent += "</div>";// 该元素div的结束
        }
        else if (element.isSelection()) {// 如果是选择框
            // 1,元素名label
            htmlContent += "<label class='paramName'>" + element.getElementName() + "</label>";
            // 2,鼠标悬停显示说明的内容
            htmlContent += "<a class='tooltips'>";
            // 3.选择框
            htmlContent += "<select id='" + elementId + "' class='paramSelect " + checkType + "'>";
            for (String option : element.getOptions()) {
                String[] optionPara = option.split("-");
                String isSelected = optionPara.length <= 2 ? "" : "selected = 'selected'";
                htmlContent += "<option value='" + optionPara[0] + "' " + isSelected + ">" + optionPara[1].trim()
                        + "</option>";
            }
            htmlContent += "</select><span>" + element.getExplan() + "</span></a><label class='isY'>";
            htmlContent += "Y".equals(checkType) ? "*</label>" : "</label>";
        }
        else {// 输入框
              // 计算输入框的最大值,取Excel中的节点类型 例如:String(20) 中的20
            String maxLength = element.getElementType();
            maxLength = TestUtils.isEmpty(maxLength) ? "" : "maxlength='"
                    + maxLength.substring(maxLength.indexOf("(") + 1, maxLength.length() - 1) + "' ";

            // 1,元素名label
            htmlContent += "<label class='paramName'>" + element.getElementName() + "</label>";
            // 4,鼠标悬停显示说明的内容
            htmlContent += "<a class='tooltips'>";
            // 2,元素值的输入框
            htmlContent += "<input id='" + elementId + "' type='text' class='paramInput " + checkType
                    + "' placeholder='" + element.getExplan() + "' " + maxLength;
            // 3,拼装必传属性,若节点必传,增加required属性,并且isY的label中含有*
            if ("Y".equals(checkType)) {
                htmlContent += "required='required' ><span>" + element.getExplan()
                        + " </span></a><label class='isY'>*</label>";
            }
            else {
                htmlContent += " ><span>" + element.getExplan() + "</span></a><label class='isY'></label>";
            }
        }
        element.setHtmlContent(htmlContent);
        return htmlContent;
    }
}
